#ifndef SPLINTER_DEFINITIONS_H
#define SPLINTER_DEFINITIONS_H

#ifndef SPLINTER_API
#ifdef _MSC_VER
#define SPLINTER_API __declspec(dllexport)
#else
#define SPLINTER_API
#endif
#endif

#ifndef NDEBUG
#include <iostream>
#include <iomanip>
#endif // NDEBUG

#include <exception>
#include <stdexcept>

#include <vector>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-attributes"
#endif
#include <Eigen/Dense>
#include <Eigen/Sparse>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif

namespace SPLINTER
{

    // Eigen vectors
    typedef Eigen::VectorXd DenseVector;
    typedef Eigen::SparseVector<double> SparseVector;

    // Eigen matrices
    typedef Eigen::MatrixXd DenseMatrix;
    typedef Eigen::SparseMatrix<double> SparseMatrix; // declares a column-major sparse matrix type of double

    class Exception : public std::exception
    {
    private:
        std::string __what;

    public:
        Exception(const std::string &what)
            : __what(what)
        {
        }

        const char *what() const throw()
        {
            return this->__what.c_str();
        }
    };

} // namespace SPLINTER

#define PRINT_VECTOR(arr)                                  \
    do                                                     \
    {                                                      \
        for (auto it = arr.begin(); it != arr.end(); it++) \
            std::cout << *it << ",";                       \
        std::cout << std::endl;                            \
    } while (false);

#endif // SPLINTER_DEFINITIONS_H
